using Core.Runtime;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;

namespace GameLauncher.Runtime
{
    /// <summary>
    /// 这里需要检查资源全部结束。TODO
    /// </summary>
    public class AssetUpdateState : HotFixState
    {
        public override async UniTask<StateResult> Execute()
        {
            await UniTask.DelayFrame(1);
            HotFixUI.RefreshDescLabel("正在检查资源更新...");
            mUpdateAsset = GetUpdateAsset();
            if (mUpdateAsset.AssetGroupCount == 0)
            {
                return StateResult.Success();
            }

            await WaitMessageClicked();
            InitializeUpdateProgress();
            UpdateAssetGroup();
            
            await WaitForUpdateComplete();
            return GetFinalResult();
        }

        private void InitializeUpdateProgress()
        {
            mTotalUpdateGroups = mUpdateAsset.UpdateGroup.Count;
            mCompletedGroups = 0;
            mHasUpdateError = false;
            mUpdateCompletionSource = new UniTaskCompletionSource();
        }

        private async UniTask WaitMessageClicked()
        {
            var taskCompletionSource = new UniTaskCompletionSource();
            HotFixUI.ShowOneMessageBox(
                $"发现 {mUpdateAsset.AssetGroupCount} 资源个更新,大小为 {RuntimeUtil.GetByteLengthDesc(mUpdateAsset.TotalLength)}",
                () => { taskCompletionSource.TrySetResult(); });
            await taskCompletionSource.Task;
        }


        private UpdateAsset GetUpdateAsset()
        {
            UpdateAsset updateAsset = new UpdateAsset();
            List<GroupInfo> groups = AssetManager.GetAllGroupInfo();
            foreach (GroupInfo groupInfo in groups)
            {
                GroupUpdater updater = AssetManager.GetGroupUpdater(groupInfo.GroupName);
                if (updater != null)
                {
                    updateAsset.UpdateGroup.Add(groupInfo);
                    updateAsset.AssetGroupCount++;
                    updateAsset.TotalLength += updater.TotalLength;
                }
            }

            return updateAsset;
        }

        private void UpdateAssetGroup()
        {
            foreach (GroupInfo groupInfo in mUpdateAsset.UpdateGroup)
            {
                GroupUpdater updater = AssetManager.GetGroupUpdater(groupInfo.GroupName);
                if (updater != null)
                {
                    AssetManager.UpdateGroup(groupInfo.GroupName, HandleGroupUpdate);
                }
            }
        }

        private void HandleGroupUpdate(BundleUpdateResult result)
        {
            if (!result.Success)
            {
                mHasUpdateError = true;
                Debug.LogError($"资源组{result.Updater.GroupName}的资源{result.UpdateInfo.Info}更新失败");
            }
            else
            {
                Debug.Log($"资源组{result.Updater.GroupName}的资源{result.UpdateInfo.Info}更新成功");
            }

            UpdateProgress();
            CheckCompletion();
        }
        
        private void UpdateProgress()
        {
            mCompletedGroups++;
            float progress = (float)mCompletedGroups / mTotalUpdateGroups;
            HotFixUI.RefreshDownProgress(progress);
        }

        private void CheckCompletion()
        {
            if (mCompletedGroups >= mTotalUpdateGroups)
            {
                mUpdateCompletionSource.TrySetResult();
            }
        }
        
        private async UniTask WaitForUpdateComplete()
        {
            await mUpdateCompletionSource.Task;
        }
        
        private StateResult GetFinalResult()
        {
            return mHasUpdateError ? 
                StateResult.Failure("资源更新失败，请检查网络连接") : 
                StateResult.Success();
        }


        private UpdateAsset mUpdateAsset;
        private int mTotalUpdateGroups;
        private int mCompletedGroups;
        private bool mHasUpdateError;
        private UniTaskCompletionSource mUpdateCompletionSource;
    }
}